#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
内存优化工具 - 不关闭开发工具的情况下释放系统内存
适用于开发环境的内存管理
"""

import os
import sys
import time
import psutil
import platform
import subprocess
from datetime import datetime

# 定义开发工具列表，避免终止这些进程
DEV_TOOLS = [
    "Code", "VsCode", "devenv", "idea", "pycharm", "clion", "goland", 
    "webstorm", "datagrip", "phpstorm", "rider", "studio64", 
    "javaw", "java", "node", "npm", "yarn", "docker", "wsl", 
    "vmware", "Trae", "python", "powershell", "cmd"
]

def get_memory_info():
    """获取系统内存信息"""
    memory = psutil.virtual_memory()
    total_gb = round(memory.total / (1024**3), 2)
    available_gb = round(memory.available / (1024**3), 2)
    used_gb = round(memory.used / (1024**3), 2)
    usage_percent = memory.percent
    
    return {
        'total': total_gb,
        'available': available_gb,
        'used': used_gb,
        'usage_percent': usage_percent
    }

def print_memory_info(memory_info, title="系统内存状态"):
    """打印内存信息"""
    print(f"\n{title}:")
    print(f"总内存: {memory_info['total']} GB")
    print(f"已用内存: {memory_info['used']} GB")
    print(f"可用内存: {memory_info['available']} GB")
    print(f"内存使用率: {memory_info['usage_percent']}%")

def get_processes_by_memory(exclude_dev_tools=True, min_memory_mb=100):
    """获取按内存使用排序的进程列表"""
    processes = []
    
    for proc in psutil.process_iter(['pid', 'name', 'memory_info', 'cpu_percent']):
        try:
            proc_info = proc.info
            memory_mb = round(proc_info['memory_info'].rss / (1024**2), 2)
            
            # 检查是否为开发工具
            is_dev_tool = False
            if exclude_dev_tools:
                for tool in DEV_TOOLS:
                    if tool.lower() in proc_info['name'].lower():
                        is_dev_tool = True
                        break
            
            if (not exclude_dev_tools or not is_dev_tool) and memory_mb >= min_memory_mb:
                processes.append({
                    'pid': proc_info['pid'],
                    'name': proc_info['name'],
                    'memory_mb': memory_mb,
                    'cpu_percent': proc_info['cpu_percent']
                })
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass
    
    # 按内存使用量排序
    processes.sort(key=lambda x: x['memory_mb'], reverse=True)
    return processes

def print_processes(processes, title="进程列表", max_count=10):
    """打印进程信息"""
    print(f"\n{title}:")
    if not processes:
        print("  没有符合条件的进程")
        return
    
    print("  {:<8} {:<20} {:<10} {:<10}".format("PID", "进程名", "内存(MB)", "CPU(%)"))
    print("  " + "-" * 50)
    
    for proc in processes[:max_count]:
        print("  {:<8} {:<20} {:<10.2f} {:<10.1f}".format(
            proc['pid'], proc['name'], proc['memory_mb'], proc['cpu_percent']
        ))
    
    if len(processes) > max_count:
        print(f"  ... 还有 {len(processes) - max_count} 个进程")

def optimize_vmware_memory():
    """优化VMware虚拟机内存使用"""
    print("\n正在查找VMware进程...")
    vmware_processes = []
    
    for proc in psutil.process_iter(['pid', 'name', 'memory_info']):
        try:
            if 'vmware' in proc.info['name'].lower():
                memory_mb = round(proc.info['memory_info'].rss / (1024**2), 2)
                vmware_processes.append({
                    'pid': proc.info['pid'],
                    'name': proc.info['name'],
                    'memory_mb': memory_mb
                })
        except (psutil.NoSuchProcess, psutil.AccessDenied):
            pass
    
    if vmware_processes:
        print("\n发现VMware进程:")
        for proc in vmware_processes:
            print(f"  - {proc['name']} (PID: {proc['pid']}): {proc['memory_mb']} MB")
        
        print("\nVMware优化建议:")
        print("1. 在VMware中调整虚拟机内存分配，建议分配不超过物理内存的50%")
        print("2. 启用VMware内存共享技术(Memory Sharing)")
        print("3. 关闭虚拟机中不必要的服务和应用")
        print("4. 考虑使用虚拟机快照替代多个虚拟机同时运行")
    else:
        print("未发现活跃的VMware进程")

def clean_system_cache():
    """清理系统缓存"""
    print("\n正在清理系统缓存...")
    if platform.system() == "Windows":
        try:
            # 在Windows上运行内存清理命令
            subprocess.run(["rundll32.exe", "advapi32.dll,ProcessIdleTasks"], shell=True)
            print("系统缓存清理完成")
        except Exception as e:
            print(f"清理系统缓存时出错: {e}")
    else:
        print("此功能仅在Windows系统上可用")

def print_optimization_tips():
    """打印优化建议"""
    print("\n==== 内存优化建议 ====")
    print("1. 开发环境优化:")
    print("   - 调整IDE内存设置，避免过度分配")
    print("   - 关闭IDE中不必要的插件和功能")
    print("   - 使用轻量级编辑器处理简单文件")
    
    print("\n2. 虚拟机优化:")
    print("   - 减少虚拟机内存分配至最小必要值")
    print("   - 启用虚拟机内存气球技术")
    print("   - 为虚拟机设置合适的优先级")
    
    print("\n3. 系统级优化:")
    print("   - 增加系统虚拟内存(页面文件)")
    print("   - 禁用不必要的系统服务")
    print("   - 定期清理临时文件和缓存")
    
    print("\n4. 开发工作流优化:")
    print("   - 采用模块化开发，避免同时加载所有组件")
    print("   - 使用依赖缓存减少重复下载")
    print("   - 考虑使用远程开发或容器化方案")

def main():
    """主函数"""
    print("=" * 50)
    print("内存优化工具 v1.0")
    print("专为开发环境设计 - 保留开发工具运行")
    print("=" * 50)
    
    # 显示优化前的内存状态
    before_memory = get_memory_info()
    print_memory_info(before_memory, "优化前的内存状态")
    
    # 获取非开发工具的高内存进程
    non_dev_processes = get_processes_by_memory(exclude_dev_tools=True, min_memory_mb=100)
    print_processes(non_dev_processes, "可优化的非开发工具进程")
    
    # 获取开发工具进程
    dev_processes = get_processes_by_memory(exclude_dev_tools=False, min_memory_mb=100)
    dev_processes = [p for p in dev_processes if any(tool.lower() in p['name'].lower() for tool in DEV_TOOLS)]
    print_processes(dev_processes, "运行中的开发工具进程")
    
    # 优化VMware内存
    optimize_vmware_memory()
    
    # 清理系统缓存
    clean_system_cache()
    
    # 等待几秒钟让系统完成内存释放
    print("\n等待系统释放内存...")
    time.sleep(3)
    
    # 显示优化后的内存状态
    after_memory = get_memory_info()
    print_memory_info(after_memory, "优化后的内存状态")
    
    # 计算释放的内存
    freed_memory = round(after_memory['available'] - before_memory['available'], 2)
    print(f"\n释放的内存: {freed_memory} GB")
    
    # 打印优化建议
    print_optimization_tips()
    
    print("\n" + "=" * 50)
    print(f"优化完成 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print("提示: 定期运行此工具以保持系统性能")
    print("=" * 50)

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print("\n程序被用户中断")
    except Exception as e:
        print(f"程序运行出错: {e}")
    finally:
        if platform.system() == "Windows":
            input("\n按回车键退出...")
